package org.groupg.project.configmanager.util;

import jakarta.persistence.EntityManager;
import jakarta.persistence.EntityManagerFactory;
import jakarta.persistence.Persistence;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.io.IOException;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.util.HashMap;
import java.util.Map;

public class JPAUtil {
    private static final Logger logger = LoggerFactory.getLogger(JPAUtil.class);
    private static EntityManagerFactory entityManagerFactory;

    static {
        initializeDataDirectory();
        initializeEntityManagerFactory();
    }

    private static void initializeDataDirectory() {
        try {
            Path dataDir = Paths.get("data");
            if (!Files.exists(dataDir)) {
                Files.createDirectories(dataDir);
                logger.info("创建数据目录: {}", dataDir.toAbsolutePath());
            }
        } catch (IOException e) {
            logger.error("创建数据目录失败", e);
        }
    }

    private static void initializeEntityManagerFactory() {
        try {
            // 可以根据环境变量动态选择数据库
            String databaseType = System.getProperty("database.type", "h2");
            Map<String, Object> properties = new HashMap<>();

            if ("mysql".equalsIgnoreCase(databaseType)) {
                properties.put("jakarta.persistence.jdbc.driver", "com.mysql.cj.jdbc.Driver");
                properties.put("jakarta.persistence.jdbc.url",
                    "jdbc:mysql://localhost:3306/config_center?useSSL=false&serverTimezone=UTC");
                properties.put("jakarta.persistence.jdbc.user", "root");
                properties.put("jakarta.persistence.jdbc.password", "password");
                properties.put("hibernate.dialect", "org.hibernate.dialect.MySQL8Dialect");
            } else {
                // 默认使用 H2
                properties.put("jakarta.persistence.jdbc.driver", "org.h2.Driver");
                properties.put("jakarta.persistence.jdbc.url",
                    "jdbc:h2:file:./data/config_center;AUTO_SERVER=TRUE;DB_CLOSE_DELAY=-1");
                properties.put("jakarta.persistence.jdbc.user", "sa");
                properties.put("jakarta.persistence.jdbc.password", "");
                properties.put("hibernate.dialect", "org.hibernate.dialect.H2Dialect");
            }

            entityManagerFactory = Persistence.createEntityManagerFactory("config-manager-pu", properties);
            logger.info("JPA EntityManagerFactory 初始化成功，使用数据库: {}", databaseType);

        } catch (Exception e) {
            logger.error("JPA EntityManagerFactory 初始化失败", e);
            throw new RuntimeException("Failed to initialize JPA", e);
        }
    }

    public static EntityManager getEntityManager() {
        return entityManagerFactory.createEntityManager();
    }

    public static void close() {
        if (entityManagerFactory != null && entityManagerFactory.isOpen()) {
            entityManagerFactory.close();
            logger.info("JPA EntityManagerFactory 已关闭");
        }
    }

    /**
     * 在事务中执行操作
     */
    public static <T> T executeInTransaction(JPATransaction<T> operation) {
        EntityManager entityManager = getEntityManager();
        try {
            entityManager.getTransaction().begin();
            T result = operation.execute(entityManager);
            entityManager.getTransaction().commit();
            return result;
        } catch (Exception e) {
            if (entityManager.getTransaction().isActive()) {
                entityManager.getTransaction().rollback();
            }
            throw new RuntimeException("Transaction failed", e);
        } finally {
            entityManager.close();
        }
    }

    /**
     * 执行无返回值的操作
     */
    public static void executeInTransaction(JPARunnable operation) {
        executeInTransaction(entityManager -> {
            operation.execute(entityManager);
            return null;
        });
    }

    @FunctionalInterface
    public interface JPATransaction<T> {
        T execute(EntityManager entityManager);
    }

    @FunctionalInterface
    public interface JPARunnable {
        void execute(EntityManager entityManager);
    }
}